package com.example.es.service;

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.mapping.Property;
import co.elastic.clients.elasticsearch._types.mapping.TypeMapping;
import co.elastic.clients.elasticsearch.indices.*;
import co.elastic.clients.util.ObjectBuilder;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.HashMap;
import java.util.function.Function;

@Service
@Slf4j
@RequiredArgsConstructor
public class IndexServiceImpl implements IndexService {

    private final ElasticsearchClient elasticsearchClient;

    /**
     * 根据索引名称创建索引
     */
    @Override
    public void createIndex(String name) throws IOException {
        CreateIndexResponse response = elasticsearchClient.indices().create(c -> c.index(name));
        log.info("createIndex方法，acknowledged={}", response.acknowledged());
    }

    /**
     * 创建索引
     * @param name
     *            - 索引名称
     * @param settingFn
     *            - 索引参数
     * @param mappingFn
     *            - 索引结构
     */
    @Override
    public void createIndex(String name,
                       Function<IndexSettings.Builder, ObjectBuilder<IndexSettings>> settingFn,
                       Function<TypeMapping.Builder, ObjectBuilder<TypeMapping>> mappingFn) throws IOException {
        CreateIndexResponse response = elasticsearchClient
                .indices()
                .create(c -> c
                        .index(name)
                        .settings(settingFn)
                        .mappings(mappingFn)
                );
        log.info("createIndex方法，acknowledged={}", response.acknowledged());
    }

    /**
     * 根据索引名称删除索引
     */
    @Override
    public void deleteIndex(String name) throws IOException {
        DeleteIndexResponse response = elasticsearchClient.indices().delete(c -> c.index(name));
        log.info("deleteIndex方法，acknowledged={}", response.acknowledged());
    }

    /**
     * 更新索引
     * @param name
     *            - 索引名称
     * @param propertyMap
     *            - 索引字段，每个字段都有自己的property
     */
    @Override
    public void updateIndexProperty(String name, HashMap<String, Property> propertyMap) throws IOException {
        PutMappingResponse response = elasticsearchClient.indices()
                .putMapping(typeMappingBuilder ->
                                typeMappingBuilder
                                .index(name)
                                .properties(propertyMap)
        );
        log.info("updateIndexMapping方法，acknowledged={}", response.acknowledged());
    }

    /**
     * 查询索引列表
     */
    @Override
    public GetIndexResponse getIndexList() throws IOException {
        //使用 * 或者 _all都可以
        GetIndexResponse response = elasticsearchClient.indices().get(builder -> builder.index("_all"));
        log.info("getIndexList方法，response.result()={}", response.result().toString());
        return response;
    }

    /**
     * 查询索引详情
     */
    @Override
    public GetIndexResponse getIndexDetail(String name) throws IOException {
        GetIndexResponse response = elasticsearchClient.indices().get(builder -> builder.index(name));
        log.info("getIndexDetail方法，response.result()={}", response.result().toString());
        return response;
    }

    /**
     * 根据索引名称查询索引是否存在
     */
    @Override
    public boolean indexExists(String name) throws IOException {
        return elasticsearchClient.indices().exists(b -> b.index(name)).value();
    }
}
